package de.koller.oceanFramework.thread;

public class Pipeline {
	
	private final PipeEntity[] pipes;
	private boolean ready = false;

	public Pipeline( IPipe... pipes ) {
		this.pipes = new PipeEntity[pipes.length];
		for( int i = 0; i < pipes.length; i++ )
			this.pipes[i] = new PipeEntity( pipes[i] );
	}
	
	public void stepPipes() {
		ready = false;
		for( PipeEntity p : pipes )
			p.startMe();
		
		synchronized( this ) {
			while( !ready )
				try { this.wait(); } catch( InterruptedException ex ) {}
		}
	}
	
	private synchronized void iAmReady() {
		for( PipeEntity p : pipes )
			if( !p.ready )
				return;
		
		ready = true;
		this.notifyAll();
	}
	
	private class PipeEntity extends Thread {
		private final IPipe pipe;
		private boolean ready = true;
		
		private PipeEntity( IPipe pipe ) {
			this.pipe = pipe;
			this.setDaemon( true );
			this.setName( pipe.getName() );
			this.start();
		}

		private synchronized void startMe() {
			ready = false;
			this.notifyAll();
		}
		
		@Override
		public void run() {
			try {
				while( !this.isInterrupted() ) {
					synchronized( this ) {
						while( ready )
							this.wait();
					}
					
					pipe.updateSubStep();
					
					ready = true;
					Pipeline.this.iAmReady();
				}
			} catch( InterruptedException ex ) {}
		}
		
	}
	
}
